#include "../game.h"
#include "pjas.h"
#include "bonde.h"

/*---------------------------------

Bonde::Bonde( bool spelare, short x, short y )
virtual
Konstruktor. Sätter bild, funktionspekare och pjästyp

---------------------------------*/

Bonde::Bonde( bool spelare, short x, short y ) : Pjas(spelare, x, y) {
	bild = video.loadImage( spelare == VIT ? "vit_bonde.bmp" : "svart_bonde.bmp" );
	typ = BONDE;

	if( spelare == VIT ) {
		md_bool_ptr = &Bonde::mojligtDrag_vit;
		md_void_ptr = &Bonde::mojligtDrag_vit;
	}
	else {
		md_bool_ptr = &Bonde::mojligtDrag_svart;
		md_void_ptr = &Bonde::mojligtDrag_svart;
	}
}

/*---------------------------------

Bonde::mojligtDrag( short x, short y )
overloadad, virtual (från Pjas)
Bonden kallar denna till en position x,y för att se om bonden kan gå dit.
Return: 0 för ogiltigt, 1 för giltigt

---------------------------------*/

bool Bonde::mojligtDrag( short x, short y ) {

	// Om det står en pjäs på x,y och spelarens ägare är bondens ägare, är draget ogiltigt.
	if( game->pjasArray[x][y] != NULL && game->pjasArray[x][y]->spelare == spelare) {
		return 0;
	}

	// Annars, kör rätt funktion via funktionspekaren och returnera svaret.
	return (*this.*md_bool_ptr)( x, y );

}

bool Bonde::mojligtDrag_vit( short x, short y ) {
	// Om x-värdet är bevarat, och den önskade positionen är tom
	if( x == xpos && game->pjasArray[x][y] == NULL ) {
		// Ett steg uppåt -> draget giltigt
		if( y == ypos-1 ) {
			return 1;
		}
		// Två steg uppåt från ursprungsposition -> draget giltigt
		if( y == ypos-2 && ypos == 6 && !game->pjasArray[x][5] ) {
			return 1;
		}
	}

	// Vid en passant. x är ett steg åt sidan, y ett steg uppåt, pjasArray är inte tom, pjäsen är en fiendebonde.
	else if( (x == xpos-1 || x == xpos+1) && y == ypos-1 && game->pjasArray[x][y] != NULL && game->pjasArray[x][y]->spelare == SVART ) {
		return 1;
	}
	// Annars är draget ogiltigt
	return 0;
}

bool Bonde::mojligtDrag_svart( short x, short y ) {
	// Om x-värdet är bevarat, och den önskade positionen är tom
	if( x == xpos && game->pjasArray[x][y] == NULL ) {
		// Ett steg nedåt -> draget giltigt
		if( y == ypos+1 ) {
			return 1;
		}
		// Två steg nedåt från ursprungsposition -> draget giltigt
		if( y == ypos+2 && ypos == 1 && !game->pjasArray[x][2] ) {
			return 1;
		}
	}

	// Vid en passant. x är ett steg åt sidan, y ett steg nedåt, pjasArray är inte tom, pjäsen är en fiendebonde.
	else if( (x == xpos-1 || x == xpos+1) && y == ypos+1 && game->pjasArray[x][y] != NULL && game->pjasArray[x][y]->spelare == VIT ) {
		return 1;
	}
	// Annars är draget ogiltigt
	return 0;
}

/*---------------------------------

Bonde::mojligtDrag( void )
overloadad, virtual (från Pjas)
Bonden kallar denna funktion för att fylla mojligaDrag med möjliga drag.
En "generaliserad" funktion av mojligtDrag(x,y).

---------------------------------*/

void Bonde::mojligtDrag( void ) {
	for( int i = 0; i < 8; i++ ) {
		for( int j = 0; j < 8; j++ ) {
			mojligaDrag[i][j] = 0;
		}
	}
	
	int rad_ett_fram = ypos + ( spelare == VIT ? -1 : 1 );
	int rad_tva_fram = ypos + ( spelare == VIT ? -2 : 2 );
	
	// Kan den gå ett steg framåt?
	if( game->pjasArray[xpos][rad_ett_fram] == NULL ) {
		mojligaDrag[xpos][rad_ett_fram] = 1;
		
		// Om ja, kan den gå två steg framåt?
		if (game->pjasArray[xpos][rad_tva_fram] == NULL ) {
			mojligaDrag[xpos][rad_tva_fram] = 1;
		}
	}
	
	// Kan den ta en pjäs?
	Pjas* test;
	if ( xpos > 0 ) {
		//Vanligt sätt
		test = game->pjasArray[xpos-1][rad_ett_fram];
		if( test && test->spelare == !spelare )
			mojligaDrag[xpos-1][rad_ett_fram] = 2;
		
		//En passant
		test = game->pjasArray[xpos-1][ypos];
		if( test && test->spelare != spelare && test->typ == BONDE )
			mojligaDrag[xpos-1][rad_ett_fram] = 2;
	}
	if ( xpos < 7 ) {
		//Vanligt sätt
		test = game->pjasArray[xpos+1][rad_ett_fram];
		if( test && test->spelare == !spelare )
			mojligaDrag[xpos+1][rad_ett_fram] = 2;
		
		//En passant
		test = game->pjasArray[xpos+1][ypos];
		if( test && test->spelare != spelare && test->typ == BONDE )
			mojligaDrag[xpos+1][rad_ett_fram] = 2;
	}
}

void Bonde::mojligtDrag_vit( void ) {

	// Kan den gå ett steg framåt?
	if( game->pjasArray[xpos][ypos-1] == NULL ) {
		mojligaDrag[xpos][ypos-1] = 1;

		// Om ja, kan den gå två steg framåt?
		if( game->pjasArray[xpos][ypos-2] == NULL ) {
			mojligaDrag[xpos][ypos-2] = 1;
		}
	}

	// Kan den ta en pjäs?
	if( game->pjasArray[xpos-1][ypos-1] != NULL && game->pjasArray[xpos-1][ypos-1]->spelare == SVART ) {
		mojligaDrag[xpos-1][ypos-1] = 1;
	}

	if( game->pjasArray[xpos+1][ypos-1] != NULL && game->pjasArray[xpos+1][ypos-1]->spelare == SVART ) {
		mojligaDrag[xpos+1][ypos-1] = 1;
	}

	// Kan den göra en passant?
	if( game->pjasArray[xpos-1][ypos] != NULL && game->pjasArray[xpos-1][ypos]->spelare == SVART && game->pjasArray[xpos-1][ypos]->typ == BONDE ) {
		mojligaDrag[xpos-1][ypos-1] = 1;
	}

	if( game->pjasArray[xpos+1][ypos] != NULL && game->pjasArray[xpos+1][ypos]->spelare == SVART && game->pjasArray[xpos+1][ypos]->typ == BONDE ) {
		mojligaDrag[xpos+1][ypos-1] = 1;
	}
}

void Bonde::mojligtDrag_svart( void ) {

	// Kan den ta ett steg framåt?
	if( game->pjasArray[xpos][ypos+1] == NULL ) {
		mojligaDrag[xpos][ypos+1] = 1;

		// Om ja, kan den ta två steg framåt?
		if( game->pjasArray[xpos][ypos+2] == NULL ) {
			mojligaDrag[xpos][ypos+2] = 1;
		}
	}

	// Kan den ta en pjäs?
	if( game->pjasArray[xpos-1][ypos+1] != NULL && game->pjasArray[xpos-1][ypos+1]->spelare == VIT ) {
		mojligaDrag[xpos-1][ypos+1] = 1;
	}

	if( game->pjasArray[xpos+1][ypos+1] != NULL && game->pjasArray[xpos+1][ypos+1]->spelare == VIT ) {
		mojligaDrag[xpos+1][ypos+1] = 1;
	}

	// Kan den göra en passant?
	if( game->pjasArray[xpos-1][ypos] != NULL && game->pjasArray[xpos-1][ypos]->spelare == VIT && game->pjasArray[xpos-1][ypos]->typ == BONDE ) {
		mojligaDrag[xpos-1][ypos+1] = 1;
	}

	if( game->pjasArray[xpos+1][ypos] != NULL&& game->pjasArray[xpos+1][ypos]->spelare == VIT && game->pjasArray[xpos+1][ypos]->typ == BONDE ) {
		mojligaDrag[xpos+1][ypos+1] = 1;
	}
}
